package com.interview.rpc.codec;

import com.interview.rpc.serialize.Serializer;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;

import java.util.List;

/**
 * RPC解码器
 * 
 * 继承Netty的ByteToMessageDecoder类，用于将字节流解码为Java对象
 * 按照编码时的格式，先读取长度字段，再读取相应长度的数据进行反序列化
 */
public class RpcDecoder extends ByteToMessageDecoder {
    // 要解码的目标对象类型
    private Class<?> genericClass;
    // 序列化器
    private Serializer serializer;
    
    public RpcDecoder(Class<?> genericClass, Serializer serializer) {
        this.genericClass = genericClass;
        this.serializer = serializer;
    }
    
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        // 可读字节数少于4个字节（长度字段的大小），说明连长度都还没读取完整，直接返回
        if (in.readableBytes() < 4) {
            return;
        }
        
        // 标记当前读位置，如果数据不完整可以复位
        in.markReaderIndex();
        // 读取数据长度
        int dataLength = in.readInt();
        // 如果可读字节数少于数据长度，说明数据还没接收完整，复位并等待接收完整数据
        if (in.readableBytes() < dataLength) {
            in.resetReaderIndex();
            return;
        }
        
        // 读取指定长度的字节数组
        byte[] data = new byte[dataLength];
        in.readBytes(data);
        
        // 使用序列化器将字节数组反序列化为指定类型的对象
        Object obj = serializer.deserialize(data, genericClass);
        // 将解码后的对象添加到输出列表中
        out.add(obj);
    }
}